package com.kk.springmvc.demo.controller;

import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.kk.springmvc.demo.service.IHelloService;

/**
 * 类级别：
 * -@Controller:用来标注控制器
 * -@RestController:作用通@Controller,只不过使用此注解就不需要标记@ResponseBody了
 * 
 * 方法/参数级别：
 * -@PathVariable:处理Request uri部分,不包含QueryString部分
 * -@RequestHeader,@CookieValue:处理RequestHeader部分 
 * -@RequestParam,@RequestBody:处理RequestBody部分
 * -@SessionAttributes,@ModelAttribute:处理attribute类型
*/
@Controller
// @RestController
public class HelloController extends BaseController {

    /**
     * 1.@Autowired与@Resource都可以用来装配bean,都可以写在字段上或写在setter方法上;
     * 2.@Autowired默认是按类型匹配(这个注解式spring的),如果要允许null值,必须设置required属性值为false;
     * 3.@Autowired还可以结合@Qualifier注解一起使用,来使用名称装配
     * 4.@Resource属于J2EE的,默认是按照名称进行装配,名称可以name属性指定,如果想不与spring耦合得过于紧密可以使用这个注解来进行装配
     */
    // @Autowired(required = false)
    // @Qualifier
    // @Resource
    @Autowired
    private IHelloService helloService;

    /**
     * 模板风格
     */
    @RequestMapping(value = "/mvc/{owner}")
    @ResponseBody
    public String path(@PathVariable(name = "owner") String owner) {
        return owner;
    }

    /**
     * ant风格
     */
    @RequestMapping(value = "/mvc/**")
    // @RequestMapping(value = "/mvc?") : 可匹配"/mvc1"或"/mvca", 单不能匹配"/mvc"或"/mvcaa"
    // @RequestMapping(value = "/mvc*") : 可匹配"/mvcaa"或"/mvc", 单不能匹配"/mvc/aa"
    // @RequestMapping(value = "/mvc/**/{owner}") : ant风格与模板风格混用
    @ResponseBody
    public String ant() {
        return "ant style";
    }

    /**
     * 正则表达式
     */
    @RequestMapping(value = "/mvc/{code:\\d+}-{num:\\d+}")
    @ResponseBody
    public String regular(@PathVariable(name = "code") String code, @PathVariable(name = "num") String num) {
        return code + "-" + num;
    }

    /**
     * 参数映射
     */
    // 请求中有"create"参数且请求方法为"GET", 例如:http://xxx/param1?create
    @RequestMapping(params = "create", method = RequestMethod.GET)
    // 请求中没有"create"参数且请求方法为"GET", 例如:http://xxx/param1?create2
    // @RequestMapping(params = "!create", method = RequestMethod.GET)
    // 请求中有"create"和"update"俩个参数且请求方法为"POST", 例如:http://xxx/param1?create&update
    // @RequestMapping(params = {"create", "update"}, method = RequestMethod.POST)
    // 请求中有"create=flag"参数且请求方式为"GET", 例如:http://xxx/param1?create=
    // @RequestMapping(params = "create=flag", method = RequestMethod.GET)
    @ResponseBody
    public String param() {
        return "hello param";
    }

    /**
     * 获取header参数
     */
    @RequestMapping(value = "/mvc/header")
    // HttpHeaders httpHeader
    public void header(@RequestHeader("Accept") String accept) {
        System.out.println(accept);
    }

    /**
     * 普通模式
     */
    @RequestMapping(value = "/mvc/value")
    @ResponseBody
    public String normal() {
        return "hello normal";
    }

    /**
     * 组合(或)
     */
    @RequestMapping(value = { "/mvc/com1", "/mvc/com2" })
    @ResponseBody
    public String combination() {
        return "hello combination";
    }

    /**
     * 跳转jsp页面
     */
    @RequestMapping(value = "/mvc/gotoJsp")
    public String gotoJsp() {
        return "hello";
    }

    /**
     * post
     */
    @RequestMapping(value = "/mvc/hello", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> hello(@RequestBody String requestJson, HttpServletRequest request) {
        return helloService.hello(null);
    }

}
